import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { FormattedMessage } from 'react-intl';
import Button from 'widget/Button';
import { GrayLight2 } from 'style/Color';
import { Editor, EditorState, RichUtils, convertToRaw } from 'draft-js';
import { FaLink } from 'react-icons/fa';

import decorator from './RichDecorator';
import { styleMap, getBlockStyle } from './RichStyle';
import {
  RichEditorRoot,
  RichControl,
  RichControlColumn,
  LinkControlColumn
} from './RichStyledComponent';
import { BlockStyleControls, LinkStyleControl, InlineStyleControls } from './RichTextControls';
import ToggleLink from './RichTextMethods/ToggleLink';
import EnterLink from './RichTextMethods/EnterLink';

const URLWrap = value => {
  let url = value;
  if (!url.startsWith('http://') && !url.startsWith('https://')) {
    url = `http://${value}`;
  }
  return url;
};

const FaContainer = styled.div`
  margin-right: 10px;
  display: inline-flex;
  align-items: center;
`;

class RichTextEditor extends Component {
  constructor(props) {
    super(props);
    this.state = { editorState: EditorState.createEmpty(decorator), controlSlide: false };

    this.inputRef = React.createRef();
    this.editorRef = React.createRef();
    this.focus = () => this.editorRef.current.focus();
    this.onChange = editorState => {
      this.setState({ editorState });
    };

    this.handleLinkKeyPress = this.handleLinkKeyPress.bind(this);
    this.handleKeyCommand = this.handleKeyCommand.bind(this);
    this.onTab = this.onTab.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.toggleBlockType = this.toggleBlockType.bind(this);
    this.toggleInlineStyle = this.toggleInlineStyle.bind(this);
    this.promptForLink = this.promptForLink.bind(this);
    this.submitForLink = this.submitForLink.bind(this);
  }

  onTab(e) {
    const maxDepth = 4;
    this.onChange(RichUtils.onTab(e, this.state.editorState, maxDepth));
  }

  getRaw() {
    const { editorState } = this.state;
    const content = editorState.getCurrentContent();
    return convertToRaw(content);
  }

  handleKeyCommand(command) {
    const { editorState } = this.state;
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      this.onChange(newState);
      return true;
    }
    return false;
  }

  toggleBlockType(blockType) {
    this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
  }

  toggleInlineStyle(inlineStyle) {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, inlineStyle));
  }

  handleBlur() {
    let { controlSlide } = this.state;
    controlSlide = false;
    this.setState({ controlSlide });
  }

  handleLinkKeyPress(e) {
    if (e.nativeEvent.keyCode === 13) {
      this.submitForLink();
    }
  }

  promptForLink() {
    let { controlSlide } = this.state;
    controlSlide = true;
    this.setState({ controlSlide }, () => {
      setTimeout(() => {
        this.inputRef.current.focus();
      }, 300);
    });
  }

  submitForLink() {
    const value = this.inputRef.current.value;
    if (value.length === 0) {
      return;
    }

    const linkText = URLWrap(value);
    const { editorState } = this.state;
    const selection = editorState.getSelection();
    const isCollapsed = selection.isCollapsed();
    if (isCollapsed) {
      this.enterLink(linkText);
    } else {
      this.toggleLink(linkText);
    }
    this.inputRef.current.value = '';
  }

  toggleLink(linkText) {
    let { controlSlide } = this.state;
    controlSlide = false;
    const { editorState } = this.state;
    const newEditorState = ToggleLink({ editorState, linkText });

    this.setState(
      {
        editorState: newEditorState,
        controlSlide
      },
      () => {
        setTimeout(() => this.focus(), 0);
      }
    );
  }

  enterLink(linkText) {
    const { editorState } = this.state;
    const newEditorState = EnterLink({ editorState, linkText });
    this.setState({ editorState: newEditorState });
  }

  render() {
    const { editorState, controlSlide } = this.state;

    let className = 'Rich-editor';
    const contentState = editorState.getCurrentContent();
    if (!contentState.hasText()) {
      if (
        contentState
          .getBlockMap()
          .first()
          .getType() !== 'unstyled'
      ) {
        className += ' Rich-hidePlaceholder';
      }
    }

    return (
      <RichEditorRoot>
        <RichControl>
          <RichControlColumn style={{ marginTop: controlSlide ? -51 : 0 }}>
            <InlineStyleControls editorState={editorState} onToggle={this.toggleInlineStyle} />
            <LinkStyleControl editorState={editorState} onToggle={this.promptForLink} />
            <BlockStyleControls editorState={editorState} onToggle={this.toggleBlockType} />
          </RichControlColumn>
          <LinkControlColumn>
            <FaContainer>
              <FaLink style={{ color: GrayLight2 }} />
            </FaContainer>
            <FormattedMessage id="editor.enter.placeholder">
              {([txt]) => (
                <input
                  ref={this.inputRef}
                  placeholder={txt}
                  onKeyPress={this.handleLinkKeyPress}
                  onBlur={this.handleBlur}
                />
              )}
            </FormattedMessage>
            <Button theme="normal" bold onClick={this.submitForLink}>
              <FormattedMessage id="editor.enter" />
            </Button>
          </LinkControlColumn>
        </RichControl>
        <div role="button" tabIndex="0" className={className} onClick={this.focus}>
          <FormattedMessage id={`editor.placeholder.${this.props.type}`}>
            {([txt]) => (
              <Editor
                blockStyleFn={getBlockStyle}
                customStyleMap={styleMap}
                editorState={editorState}
                handleKeyCommand={this.handleKeyCommand}
                onChange={this.onChange}
                onTab={this.onTab}
                placeholder={txt}
                ref={this.editorRef}
                spellCheck
              />
            )}
          </FormattedMessage>
        </div>
      </RichEditorRoot>
    );
  }
}

RichTextEditor.propTypes = {
  type: PropTypes.string.isRequired
};

export default RichTextEditor;
